#include <map>
#include <queue>
#include <vector>
#include <string>
#include <iostream>
#include <algorithm>

using i64 = long long;

int dx[] = { 0, 1, -1, 0 };
int dy[] = { 1, 0, 0, -1 };

int n, m;
int g_tot;
std::vector<std::string> map;
std::vector<std::vector<int>> id;
std::vector<std::vector<int>> e;

bool inside(int i, int j) {
    return i >= 0 && i < n && j >= 0 && j < m;
}

void pre_dfs(int i, int j) {
    id[i][j] = g_tot++;
    for (int k = 0; k < 4; ++k) {
        int x = i + dx[k], y = j + dy[k];
        if (inside(x, y) && map[x][y] != '#' && id[x][y] == -1)
            pre_dfs(x, y);
    }
}

int dfc, tr_tot;
std::vector<int> dfn, low, stk;
std::vector<std::vector<int>> tr;

void add_edge(int x, int y) {
    tr[x].push_back(y);
    tr[y].push_back(x);
}

void Tarjan(int u) {
    dfn[u] = low[u] = dfc++;
    stk.push_back(u);
    for (auto v : e[u]) {
        if (dfn[v] == -1) {
            Tarjan(v);
            low[u] = std::min(low[u], low[v]);
            if (low[v] == dfn[u]) {
                int x;
                do {
                    x = stk.back();
                    stk.pop_back();
                    add_edge(tr_tot, x);
                } while (x != v);
                add_edge(tr_tot, u);
                tr_tot++;
            }
        }
        else low[u] = std::min(low[u], dfn[v]);
    }
}

std::vector<int> dep, size, fa;

void tr_dfs(int u, int fat) {
    if (~fat) dep[u] = dep[fat] + 1;
    fa[u] = fat;
    size[u] = u < g_tot;
    for (auto v : tr[u]) {
        if (v == fat) continue;
        tr_dfs(v, u);
        size[u] += size[v];
    }
}

std::vector<std::vector<std::vector<bool>>> can;

bool reach(int x, int y) {
    if (fa[x] == fa[y]) return true;
    if (~fa[x] && fa[fa[x]] == y) return true;
    if (~fa[y] && fa[fa[y]] == x) return true;
    return false;
}

void bfs(int sx, int sy) {
    can.resize(n, std::vector<std::vector<bool>>(m, std::vector<bool>(4, false)));
    struct Point { int x, y, d; };
    std::queue<Point> que;
    for (int k = 0; k < 4; ++k) {
        int x = sx + dx[k], y = sy + dy[k];
        if (inside(x, y) && ~id[x][y]) {
            can[sx][sy][k] = true;
            que.push({sx, sy, k});
        }
    }
    while (!que.empty()) {
        auto p = que.front();
        que.pop();
        int i = p.x, j = p.y, d = p.d;
        // go straignt
        int x = i + dx[d], y = j + dy[d];
        int xx = x + dx[d], yy = y + dy[d];
        if (inside(xx, yy) && ~id[xx][yy] && !can[x][y][d]) {
            can[x][y][d] = true;
            que.push({x, y, d});
        }
        // turn around
        for (int k = 0; k < 4; ++k) {
            if (can[i][j][k]) continue;
            int tx = i + dx[k], ty = j + dy[k];
            if (inside(tx, ty) && ~id[tx][ty] && reach(id[x][y], id[tx][ty])) {
                can[i][j][k] = true;
                que.push({i, j, k});
            }
        }
    }
}

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);

    std::cin >> n >> m;
    map.resize(n);
    int sx = -1, sy = -1;
    for (int i = 0; i < n; ++i) {
        std::cin >> map[i];
        for (int j = 0; j < m; ++j)
            if (map[i][j] == 'X')
                sx = i, sy = j;
    }
    id.resize(n, std::vector<int>(m, -1));
    pre_dfs(sx, sy);
    e.resize(g_tot);
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < m; ++j) {
            if (id[i][j] == -1) continue;
            for (int k = 0; k < 4; ++k) {
                int x = i + dx[k], y = j + dy[k];
                if (inside(x, y) && ~id[x][y])
                    e[id[i][j]].push_back(id[x][y]);
            }
        }
    }

    tr_tot = g_tot;
    dfn.resize(g_tot, -1);
    low.resize(g_tot, -1);
    tr.resize(g_tot * 2);
    Tarjan(id[sx][sy]);
    dep.resize(tr_tot);
    size.resize(tr_tot);
    fa.resize(tr_tot);
    tr_dfs(id[sx][sy], -1);

    bfs(sx, sy);

    i64 ans = 0;
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < m; ++j) {
            if (id[i][j] == -1 || (i == sx && j == sy)) continue;
            bool vis = false;
            std::map<int, bool> alr;
            for (int k = 0; k < 4; ++k) {
                if (!can[i][j][k]) continue;
                int x = i + dx[k], y = j + dy[k];
                if (!inside(x, y) || id[x][y] == -1) continue;
                int u = id[i][j], v = id[x][y];
                if (!reach(u, v)) continue;
                if (~fa[v] && fa[fa[v]] == u) {
                    if (!alr.count(fa[v])) {
                        ans += size[fa[v]];
                        alr[fa[v]] = true;
                    }
                }
                else {
                    if (!vis) {
                        ans += g_tot - size[u] - 1;
                        vis = true;
                    }
                }
            }
        }
    }
    std::cout << ans << '\n';

    return 0;
}